Add functions which allow faster insertion of rows in sorted list stores.
authorMatthias Clasen <mclasen@redhat.com>
Thu, 9 Dec 2004 06:21:39 +0000 (06:21 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Thu, 9 Dec 2004 06:21:39 +0000 (06:21 +0000)
2004-12-09  Matthias Clasen  <mclasen@redhat.com>

* gtk/gtkliststore.h:
* gtk/gtkliststore.c (gtk_list_store_insert_with_values):
(gtk_list_store_insert_with_valuesv): Add functions which allow
faster insertion of rows in sorted list stores.  (#160063)

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/reference/ChangeLog
docs/reference/gtk/gtk-sections.txt
gtk/gtkliststore.c
gtk/gtkliststore.h

index 89e9a9ec319d0e08ec7da80c464027cf8c3ff7ad..6024a1e921183601df2ee890e3955234e714a79a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-12-09  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkliststore.h: 
+       * gtk/gtkliststore.c (gtk_list_store_insert_with_values): 
+       (gtk_list_store_insert_with_valuesv): Add functions which allow
+       faster insertion of rows in sorted list stores.  (#160063)
+
 2004-12-08  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkcombobox.c (gtk_combo_box_set_wrap_width): Fix a typo
index 89e9a9ec319d0e08ec7da80c464027cf8c3ff7ad..6024a1e921183601df2ee890e3955234e714a79a 100644 (file)
@@ -1,3 +1,10 @@
+2004-12-09  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkliststore.h: 
+       * gtk/gtkliststore.c (gtk_list_store_insert_with_values): 
+       (gtk_list_store_insert_with_valuesv): Add functions which allow
+       faster insertion of rows in sorted list stores.  (#160063)
+
 2004-12-08  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkcombobox.c (gtk_combo_box_set_wrap_width): Fix a typo
index 89e9a9ec319d0e08ec7da80c464027cf8c3ff7ad..6024a1e921183601df2ee890e3955234e714a79a 100644 (file)
@@ -1,3 +1,10 @@
+2004-12-09  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkliststore.h: 
+       * gtk/gtkliststore.c (gtk_list_store_insert_with_values): 
+       (gtk_list_store_insert_with_valuesv): Add functions which allow
+       faster insertion of rows in sorted list stores.  (#160063)
+
 2004-12-08  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkcombobox.c (gtk_combo_box_set_wrap_width): Fix a typo
index 89e9a9ec319d0e08ec7da80c464027cf8c3ff7ad..6024a1e921183601df2ee890e3955234e714a79a 100644 (file)
@@ -1,3 +1,10 @@
+2004-12-09  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtkliststore.h: 
+       * gtk/gtkliststore.c (gtk_list_store_insert_with_values): 
+       (gtk_list_store_insert_with_valuesv): Add functions which allow
+       faster insertion of rows in sorted list stores.  (#160063)
+
 2004-12-08  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkcombobox.c (gtk_combo_box_set_wrap_width): Fix a typo
index 10b2d10df34ce5fc991027b3b62514673de5f7f9..6753a66810808efece2bb0a464721dd81950bd48 100644 (file)
@@ -1,3 +1,7 @@
+2004-12-09  Matthias Clasen  <mclasen@redhat.com>
+
+       * gtk/gtk-sections.txt: Add new list store methods.
+
 2004-12-08  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtk-sections.txt: Add gtk_text_view_get_iter_at_position.
index d0efc4cd5d1806844c9ef81027f565ae3f7e90cb..ec00deba4f08f40277ca8ab30b4326e1f89aa00a 100644 (file)
@@ -4268,6 +4268,8 @@ gtk_list_store_remove
 gtk_list_store_insert
 gtk_list_store_insert_before
 gtk_list_store_insert_after
+gtk_list_store_insert_with_values
+gtk_list_store_insert_with_valuesv
 gtk_list_store_prepend
 gtk_list_store_append
 gtk_list_store_clear
index 9f175cf26661ca8510424621e834ed91a7bda041..29ed16ea924a57e9246132ef2220fdef1971b283 100644 (file)
@@ -778,29 +778,16 @@ gtk_list_store_set_value (GtkListStore *list_store,
     }
 }
 
-/**
- * gtk_list_store_set_valist:
- * @list_store: A #GtkListStore
- * @iter: A valid #GtkTreeIter for the row being modified
- * @var_args: va_list of column/value pairs
- *
- * See gtk_list_store_set(); this version takes a va_list for use by language
- * bindings.
- *
- **/
-void
-gtk_list_store_set_valist (GtkListStore *list_store,
-                           GtkTreeIter  *iter,
-                           va_list      var_args)
+static void
+gtk_list_store_set_valist_internal (GtkListStore *list_store,
+                                   GtkTreeIter  *iter,
+                                   gboolean     *emit_signal,
+                                   gboolean     *maybe_need_sort,
+                                   va_list       var_args)
 {
   gint column;
-  gboolean emit_signal = FALSE;
-  gboolean maybe_need_sort = FALSE;
   GtkTreeIterCompareFunc func = NULL;
 
-  g_return_if_fail (GTK_IS_LIST_STORE (list_store));
-  g_return_if_fail (VALID_ITER (iter, list_store));
-
   column = va_arg (var_args, gint);
 
   if (GTK_LIST_STORE_IS_SORTED (list_store))
@@ -821,7 +808,7 @@ gtk_list_store_set_valist (GtkListStore *list_store,
     }
 
   if (func != _gtk_tree_data_list_compare_func)
-    maybe_need_sort = TRUE;
+    *maybe_need_sort = TRUE;
 
   while (column != -1)
     {
@@ -848,20 +835,47 @@ gtk_list_store_set_valist (GtkListStore *list_store,
        }
 
       /* FIXME: instead of calling this n times, refactor with above */
-      emit_signal = gtk_list_store_real_set_value (list_store,
-                                                  iter,
-                                                  column,
-                                                  &value,
-                                                  FALSE) || emit_signal;
-
+      *emit_signal = gtk_list_store_real_set_value (list_store,
+                                                   iter,
+                                                   column,
+                                                   &value,
+                                                   FALSE) || *emit_signal;
+      
       if (func == _gtk_tree_data_list_compare_func &&
          column == list_store->sort_column_id)
-       maybe_need_sort = TRUE;
+       *maybe_need_sort = TRUE;
 
       g_value_unset (&value);
 
       column = va_arg (var_args, gint);
     }
+}
+
+/**
+ * gtk_list_store_set_valist:
+ * @list_store: A #GtkListStore
+ * @iter: A valid #GtkTreeIter for the row being modified
+ * @var_args: va_list of column/value pairs
+ *
+ * See gtk_list_store_set(); this version takes a va_list for use by language
+ * bindings.
+ *
+ **/
+void
+gtk_list_store_set_valist (GtkListStore *list_store,
+                           GtkTreeIter  *iter,
+                           va_list      var_args)
+{
+  gboolean emit_signal = FALSE;
+  gboolean maybe_need_sort = FALSE;
+
+  g_return_if_fail (GTK_IS_LIST_STORE (list_store));
+  g_return_if_fail (VALID_ITER (iter, list_store));
+
+  gtk_list_store_set_valist_internal (list_store, iter, 
+                                     &emit_signal, 
+                                     &maybe_need_sort,
+                                     var_args);
 
   if (maybe_need_sort && GTK_LIST_STORE_IS_SORTED (list_store))
     gtk_list_store_sort_iter_changed (list_store, iter, list_store->sort_column_id);
@@ -960,9 +974,9 @@ gtk_list_store_remove (GtkListStore *list_store,
  *
  * Creates a new row at @position.  @iter will be changed to point to this new
  * row.  If @position is larger than the number of rows on the list, then the
- * new row will be appended to the list.  The row will be empty before this
- * function is called.  To fill in values, you need to call gtk_list_store_set()
- * or gtk_list_store_set_value().
+ * new row will be appended to the list. The row will be empty after this
+ * function is called.  To fill in values, you need to call 
+ * gtk_list_store_set() or gtk_list_store_set_value().
  *
  **/
 void
@@ -1009,10 +1023,10 @@ gtk_list_store_insert (GtkListStore *list_store,
  * @iter: An unset #GtkTreeIter to set to the new row
  * @sibling: A valid #GtkTreeIter, or %NULL
  *
- * Inserts a new row before @sibling. If @sibling is %NULL, then the row will be
- * appended to the end of the list. @iter will be changed to point to this new 
- * row. The row will be empty before this function is called. To fill in values,
- * you need to call gtk_list_store_set() or gtk_list_store_set_value().
+ * Inserts a new row before @sibling. If @sibling is %NULL, then the row will 
+ * be appended to the end of the list. @iter will be changed to point to this 
+ * new row. The row will be empty after this function is called. To fill in 
+ * values, you need to call gtk_list_store_set() or gtk_list_store_set_value().
  *
  **/
 void
@@ -1133,8 +1147,8 @@ gtk_list_store_clear (GtkListStore *list_store)
  * @list_store: A #GtkListStore.
  * @iter: A #GtkTreeIter.
  *
- * WARNING: This function is slow. Only use it for debugging and/or testing
- * purposes.
+ * <warning>This function is slow. Only use it for debugging and/or testing
+ * purposes.</warning>
  *
  * Checks if the given iter is a valid iter for this #GtkListStore.
  *
@@ -1870,3 +1884,189 @@ gtk_list_store_has_default_sort_func (GtkTreeSortable *sortable)
 
   return (list_store->default_sort_func != NULL);
 }
+
+
+/**
+ * gtk_list_store_insert_with_values:
+ * @list_store: A #GtkListStore
+ * @iter: An unset #GtkTreeIter to set to the new row
+ * @position: position to insert the new row
+ * @Varargs: pairs of column number and value, terminated with -1
+ *
+ * Creates a new row at @position.  @iter will be changed to point to this new
+ * row.  If @position is larger than the number of rows on the list, then the
+ * new row will be appended to the list. The row will be filled with the 
+ * values given to this function. 
+ * 
+ * Calling
+ * <literal>gtk_list_store_insert_with_values(list_store, iter, position...)</literal> 
+ * has the same effect as calling 
+ * <informalexample><programlisting>
+ * gtk_list_store_insert (list_store, iter, position);
+ * gtk_list_store_set (list_store_iter, ...);
+ * </programlisting></informalexample>
+ * with the difference that the former will only emit a row_inserted signal,
+ * while the latter will emit row_inserted, row_changed and, if the list store
+ * is sorted, rows_reordered. Since emitting the rows_reordered signal
+ * repeatedly can affect the performance of the program, 
+ * gtk_list_store_insert_with_values() should generally be preferred when
+ * inserting rows in a sorted list store.
+ *
+ * Since: 2.6
+ */
+void
+gtk_list_store_insert_with_values (GtkListStore *list_store,
+                                  GtkTreeIter  *iter,
+                                  gint          position,
+                                  ...)
+{
+  GtkTreePath *path;
+  GtkSequence *seq;
+  GtkSequencePtr ptr;
+  gint length;
+  gboolean changed = FALSE;
+  gboolean maybe_need_sort = FALSE;
+  va_list var_args;
+
+  /* FIXME: refactor to reduce overlap with gtk_list_store_set() */
+  g_return_if_fail (GTK_IS_LIST_STORE (list_store));
+  g_return_if_fail (iter != NULL);
+
+  list_store->columns_dirty = TRUE;
+
+  seq = list_store->seq;
+
+  length = _gtk_sequence_get_length (seq);
+  if (position > length)
+    position = length;
+
+  ptr = _gtk_sequence_get_ptr_at_pos (seq, position);
+  ptr = _gtk_sequence_insert (ptr, NULL);
+
+  iter->stamp = list_store->stamp;
+  iter->user_data = ptr;
+
+  g_assert (VALID_ITER (iter, list_store));
+
+  list_store->length++;  
+
+  va_start (var_args, position);
+  gtk_list_store_set_valist_internal (list_store, iter, 
+                                     &changed, &maybe_need_sort,
+                                     var_args);
+  va_end (var_args);
+
+  /* Don't emit rows_reordered here */
+  if (maybe_need_sort && GTK_LIST_STORE_IS_SORTED (list_store))
+    _gtk_sequence_sort_changed (iter->user_data,
+                               gtk_list_store_compare_func,
+                               list_store);
+
+  /* Just emit row_inserted */
+  path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
+  gtk_tree_model_row_inserted (GTK_TREE_MODEL (list_store), path, iter);
+  gtk_tree_path_free (path);
+}
+
+
+/**
+ * gtk_list_store_insert_with_valuesv:
+ * @list_store: A #GtkListStore
+ * @iter: An unset #GtkTreeIter to set to the new row
+ * @position: position to insert the new row
+ * @columns: an array of column numbers
+ * @values: an array of GValues 
+ * @n_values: the length of the @columns and @values arrays
+ * 
+ * A variant of gtk_list_Store_insert_with_values() which
+ * takes the columns and values as two arrays, instead of
+ * varargs. This function is mainly intended for 
+ * language-bindings.
+ *
+ * Since: 2.6
+ */
+void
+gtk_list_store_insert_with_valuesv (GtkListStore *list_store,
+                                   GtkTreeIter  *iter,
+                                   gint          position,
+                                   gint         *columns, 
+                                   GValue       *values,
+                                   gint          n_values)
+{
+  GtkTreePath *path;
+  GtkSequence *seq;
+  GtkSequencePtr ptr;
+  gint length;
+  gboolean changed = FALSE;
+  gboolean maybe_need_sort = FALSE;
+  GtkTreeIterCompareFunc func = NULL;
+  gint i;
+
+  /* FIXME refactor to reduce overlap with 
+   * gtk_list_store_insert_with_values() 
+   */
+  g_return_if_fail (GTK_IS_LIST_STORE (list_store));
+  g_return_if_fail (iter != NULL);
+
+  list_store->columns_dirty = TRUE;
+
+  seq = list_store->seq;
+
+  length = _gtk_sequence_get_length (seq);
+  if (position > length)
+    position = length;
+
+  ptr = _gtk_sequence_get_ptr_at_pos (seq, position);
+  ptr = _gtk_sequence_insert (ptr, NULL);
+
+  iter->stamp = list_store->stamp;
+  iter->user_data = ptr;
+
+  g_assert (VALID_ITER (iter, list_store));
+
+  list_store->length++;  
+
+  if (GTK_LIST_STORE_IS_SORTED (list_store))
+    {
+      if (list_store->sort_column_id != -1)
+       {
+         GtkTreeDataSortHeader *header;
+         header = _gtk_tree_data_list_get_header (list_store->sort_list,
+                                                  list_store->sort_column_id);
+         g_return_if_fail (header != NULL);
+         g_return_if_fail (header->func != NULL);
+         func = header->func;
+       }
+      else
+       {
+         func = list_store->default_sort_func;
+       }
+    }
+
+  if (func != _gtk_tree_data_list_compare_func)
+    maybe_need_sort = TRUE;
+
+  for (i = 0; i < n_values; i++)
+    {
+      changed = gtk_list_store_real_set_value (list_store, 
+                                              iter, 
+                                              columns[i],
+                                              &values[i],
+                                              FALSE) || changed;
+
+      if (func == _gtk_tree_data_list_compare_func &&
+         columns[i] == list_store->sort_column_id)
+       maybe_need_sort = TRUE;
+    }
+
+  /* Don't emit rows_reordered here */
+  if (maybe_need_sort && GTK_LIST_STORE_IS_SORTED (list_store))
+    _gtk_sequence_sort_changed (iter->user_data,
+                               gtk_list_store_compare_func,
+                               list_store);
+
+  /* Just emit row_inserted */
+  path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
+  gtk_tree_model_row_inserted (GTK_TREE_MODEL (list_store), path, iter);
+  gtk_tree_path_free (path);
+}
index d653acf223ff6efdb38536fc85b35796f9c38c85..20b5acb1b7f479b2b2dd2b50e30eb05416868977 100644 (file)
@@ -101,6 +101,16 @@ void          gtk_list_store_insert_before    (GtkListStore *list_store,
 void          gtk_list_store_insert_after     (GtkListStore *list_store,
                                               GtkTreeIter  *iter,
                                               GtkTreeIter  *sibling);
+void          gtk_list_store_insert_with_values  (GtkListStore *list_store,
+                                                 GtkTreeIter  *iter,
+                                                 gint          position,
+                                                 ...);
+void          gtk_list_store_insert_with_valuesv (GtkListStore *list_store,
+                                                 GtkTreeIter  *iter,
+                                                 gint          position,
+                                                 gint         *columns, 
+                                                 GValue       *values,
+                                                 gint          n_values);
 void          gtk_list_store_prepend          (GtkListStore *list_store,
                                               GtkTreeIter  *iter);
 void          gtk_list_store_append           (GtkListStore *list_store,